package com.xuchao.protocol;

import com.xuchao.message.LoginRequestMessage;
import com.xuchao.message.Message;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.FixedLengthFrameDecoder;
import io.netty.handler.codec.LengthFieldBasedFrameDecoder;
import io.netty.handler.logging.LoggingHandler;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.lang.reflect.Field;

/**
 * @Author xuchao
 * @Date:2024/1/18 15:06
 * @description
 * @Version 1.0
 */
@Slf4j
public class TestMessageCodec {
    public static void main(String[] args) throws IOException, InstantiationException, IllegalAccessException {
        LoggingHandler loggingHandler = new LoggingHandler();
        MessageCodeSharable messageCodeSharable = new MessageCodeSharable();

        EmbeddedChannel channel = new EmbeddedChannel();
        channel.pipeline().addLast(loggingHandler);
        channel.pipeline().addLast(new LengthFieldBasedFrameDecoder(1024,12,4,0,0));
        // channel.pipeline().addLast(new MessageCodec());
        channel.pipeline().addLast(messageCodeSharable);
        LoginRequestMessage message = new LoginRequestMessage("吊炸天", "123");
        // channel.writeOutbound(message);
        ByteBuf encode = encode(message);
        ByteBuf b1 = encode.slice(0,100);
        ByteBuf b2 = encode.slice(100,encode.readableBytes()-100);
        b1.retain();
        channel.writeInbound(b1);
        channel.writeInbound(b2);
        // channel.writeInbound(encode(message));
    }

    static ByteBuf encode(Message msg) throws IOException {
        ByteBuf out = ByteBufAllocator.DEFAULT.buffer();
        //1. 4字节的魔数
        out.writeBytes(new byte[]{1,2,3,4});
        //2. 1字节的版本
        out.writeByte(1);
        //3. 1字节的序列化方式 0 jdk, 1 json  代表序列化的方式
        out.writeByte(0);
        //4. 1字节的指令类型
        out.writeByte(msg.getMessageType());
        //5 4字节的请求序号
        out.writeInt(msg.getSequenceId());
        //无意义的字节 凑够16位
        out.writeByte(0xff);
        //6 消息正文
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ObjectOutputStream oos = new ObjectOutputStream(baos);
        oos.writeObject(msg);
        byte[] bytes = baos.toByteArray();
        //7 4字节的正文长度
        out.writeInt(bytes.length);
        //8 写入内容
        out.writeBytes(bytes);
        return out;
    }
}
